/* eslint-disable import/prefer-default-export */
/* eslint-disable no-unused-vars */
/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
/* eslint-disable prefer-destructuring */
/* eslint-disable class-methods-use-this */
/* eslint-disable max-classes-per-file */
import Konva from 'konva'
import { IKonvaCommon } from '@/components/konvaUnits/common/IKonvaCommon'
import KonvaUtils from '@/components/konvaUnits/utils/konvaUtils'
import { Pillar } from '@/components/konvaUnits/common/pillar'
import { useStore } from '@/store/index'
import { DoorClass } from '@/store/door'

const drawDoorText = (id: string, length: number, text: string, dash: boolean) => {
  const group = new Konva.Group({ id: `${id}-doorText` })
  const offset: number = 20
  const arrowOffset: number = 20 / 2
  const arrowSize: number = 5

  if (dash) {
    const fenceDash = new Konva.Line({
      id: `${id}-doorText`,
      points: [0, 0, length, 0],
      dash: [10, 10],
      stroke: 'grey',
      strokeWidth: 2
    })
    group.add(fenceDash)
  } else {
    const lines = new Konva.Shape({
      id: `${id}-doorText`,
      sceneFunc(ctx) {
        ctx.fillStyle = 'grey'
        ctx.lineWidth = 0.5
        ctx.moveTo(0, 0)
        ctx.lineTo(0, offset)
        ctx.moveTo(length, 0)
        ctx.lineTo(length, offset)
        ctx.stroke()
      }
    })
    const bottomArrow = new Konva.Shape({
      id: `${id}-doorText`,
      sceneFunc(ctx, shape) {
        // top pointer
        ctx.translate(0, arrowOffset)
        ctx.moveTo(arrowSize, -arrowSize)
        ctx.lineTo(0, 0)
        ctx.lineTo(arrowSize, arrowSize)
        // line
        ctx.moveTo(0, 0)
        ctx.lineTo(length, 0)
        ctx.lineTo(length, 0)
        // bottom pointer
        ctx.moveTo(length - arrowSize, -arrowSize)
        ctx.lineTo(length, 0)
        ctx.lineTo(length - arrowSize, arrowSize)
        ctx.strokeShape(shape)
      },
      stroke: 'grey',
      strokeWidth: 0.5
    })
    group.add(bottomArrow, lines)
  }

  const bottomText = new Konva.Text({
    id: `${id}-doorText`,
    x: length / 2 - 10,
    y: dash ? arrowOffset : arrowOffset - 15,
    text: `${dash ? text : parseInt(text, 10) / 1000}${dash ? '' : 'm'}`,
    padding: 2,
    fill: 'black'
  })
  group.add(bottomText)
  return group
}

const drawJlmDoor = (id: string, start: number[], length: number, angle: number, text: string) => {
  const store = useStore()

  const group = new Konva.Group({ id: `${id}-door` })
  const fenceText = drawDoorText(id, length, text, true)
  const fence = new Konva.Line({
    points: [0, 3, length, 3],
    stroke: 'grey'
  })
  if (store.door.direction === 'LEFT') {
    const doorPoints = KonvaUtils.getAnglePoints([0, 3], -25, length)
    const door = new Konva.Line({
      id: `${id}-door`,
      points: [0, 3, doorPoints[2], doorPoints[3]],
      stroke: 'grey'
    })
    const doorMiddle = KonvaUtils.getAnglePoints([0, 3], -10, length)
    const doorLine = new Konva.Line({
      id: `${id}-door`,
      points: [doorPoints[2], doorPoints[3]]
        .concat([doorMiddle[2], doorMiddle[3]])
        .concat(length, 3),
      tension: 0.7,
      stroke: 'grey'
    })
    group.add(fenceText, fence, door, doorLine)
  } else {
    const doorPoints = KonvaUtils.getAnglePoints([length, 3], -155, length)
    const door = new Konva.Line({
      id: `${id}-door`,
      points: [length, 3, doorPoints[2], doorPoints[3]],
      stroke: 'grey'
    })
    const doorMiddle = KonvaUtils.getAnglePoints([length, 3], -170, length)
    const doorLine = new Konva.Line({
      id: `${id}-door`,
      points: [doorPoints[2], doorPoints[3]].concat([doorMiddle[2], doorMiddle[3]]).concat(0, 3),
      tension: 0.7,
      stroke: 'grey'
    })
    group.add(fenceText, fence, door, doorLine)
  }
  group.x(start[0])
  group.y(start[1])
  group.rotation(angle)
  return group
}

const drawPymDoor = (id: string, start: number[], length: number, angle: number, text: string) => {
  const store = useStore()

  const group = new Konva.Group({ id: `${id}-door` })
  const fenceText = drawDoorText(id, length, text, true)

  if (store.door.direction === 'LEFT') {
    const fence = new Konva.Line({
      points: [0, 3, length / 2, 3],
      stroke: 'grey'
    })

    const door = new Konva.Line({
      id: `${id}-door`,
      points: [-length / 6 + length / 2, -3, length / 2 + (length / 6) * 2, -3],
      stroke: 'black'
    })
    group.add(fence, fenceText, door)
  } else {
    const door = new Konva.Line({
      id: `${id}-door`,
      points: [length / 6, -3, length / 2 + length / 6, -3],
      stroke: 'black'
    })

    const fence = new Konva.Line({
      points: [length / 2, 3, length, 3],
      stroke: 'grey'
    })
    group.add(fence, fenceText, door)
  }
  group.x(start[0])
  group.y(start[1])
  group.rotation(angle)
  return group
}

const fixPillarPos = (x: number, y: number, width: number, height: number, rotation: number) => {
  const points = KonvaUtils.getAnglePoints([x, y], rotation, width)
  return [points[2], points[3]]
}

const drawDoor = (id: string, start: number[], length: number, angle: number, text: string) => {
  const store = useStore()
  if (store.door.type === 'JLM') {
    return drawJlmDoor(id, start, length, angle, text)
  }
  return drawPymDoor(id, start, length, angle, text)
}

export const drawDoorGroup = (
  id: string,
  start: number[],
  length: number,
  angle: number,
  scale: number,
  beginPillar: { id: ''; x: 0; y: 0; rotation: 0; width: 0; height: 0 },
  endPillar: { id: ''; x: 0; y: 0; rotation: 0; width: 0; height: 0 },
  addStore: boolean
) => {
  const group = new Konva.Group({ id })
  const store = useStore()
  const doorList = KonvaUtils.splitDoor(length, store.door.type)
  let startPos = start
  let beginPos = start
  let totalLength = 0
  if (beginPillar.id === '') {
    const pillar = new Pillar()
    const drawPillar = pillar.draw(id, [startPos[0], startPos[1]], angle, addStore)
    group.add(pillar.pillar)
    totalLength += store.pillar.diameter[0]
    startPos = fixPillarPos(
      drawPillar.x,
      drawPillar.y,
      drawPillar.width,
      drawPillar.height,
      drawPillar.rotation
    )
  } else {
    startPos = fixPillarPos(
      beginPillar.x,
      beginPillar.y,
      beginPillar.width,
      beginPillar.height,
      beginPillar.rotation
    )
    startPos = KonvaUtils.fixStartPos(
      startPos,
      beginPillar.rotation,
      [beginPillar.width, beginPillar.height / 2],
      angle
    )
    beginPos = startPos
  }

  for (const i in doorList) {
    doorList[i] += store.door.type === 'JLM' ? 0 : 10 + store.pillar.diameter[0]
    group.add(
      drawDoor(
        `${id}-${store.drawing.doors.size + 1}`,
        startPos,
        doorList[i] / scale,
        angle,
        doorList[i].toString()
      )
    )
    totalLength +=
      doorList[i] + 10 + (store.door.type === 'JLM' ? 0 : 10 + store.pillar.diameter[0])
    if (store.door.type === 'PYM') {
      const pillar = new Pillar()
      const points = KonvaUtils.fixRadian(startPos, angle, doorList[i] / 2 / scale)
      const drawPillar = pillar.draw(id, [points.points[2], points.points[3]], angle, addStore)
      group.add(pillar.pillar)
    }
    if (addStore) {
      store.drawingAction.setDoor(
        `${id}-${store.drawing.doors.size + 1}`,
        new DoorClass(
          startPos,
          angle,
          store.door.height,
          doorList[i],
          store.door.color,
          store.door.spacing,
          store.door.silk,
          store.door.type,
          store.door.direction,
          store.door.lock
        )
      )
    }

    const points = KonvaUtils.fixRadian(startPos, angle, doorList[i] / scale)
    startPos = [points.points[2], points.points[3]]

    if (parseInt(i, 10) === doorList.length - 1 && endPillar.id !== '') {
      break
    }

    const pillar = new Pillar()
    const drawPillar = pillar.draw(id, [points.points[2], points.points[3]], angle, addStore)
    group.add(pillar.pillar)
    totalLength += store.pillar.diameter[0]
    startPos = fixPillarPos(drawPillar.x, drawPillar.y, drawPillar.width, drawPillar.height, angle)
  }
  const groupText = drawDoorText(
    id,
    KonvaUtils.getPositionLength(beginPos, startPos),
    totalLength.toString(),
    false
  )
  const lineLength = KonvaUtils.getPositionLength(beginPos, startPos)

  const groupTextPoints = KonvaUtils.fixRadian(beginPos, angle - 90, 20).points
  groupText.x(groupTextPoints[2])
  groupText.y(groupTextPoints[3])
  groupText.rotation(angle)
  group.add(groupText)
  const rectSelect = new Konva.Rect({
    id: `${id}-rect-select`,
    x: groupTextPoints[2],
    y: groupTextPoints[3],
    rotation: angle,
    width: lineLength - 20,
    strokeEnabled: false,
    stroke: 'red',
    height: 10
  })
  group.add(rectSelect)
  rectSelect.moveToBottom()
  return { door: group, points: start.concat(startPos) }
}

export class Door implements IKonvaCommon {
  points!: number[]

  height: number = 2000

  width: number = 1400

  color: string = 'black'

  spacing: number[] = [20, 100]

  silk: number = 3

  direction: 'left' | 'right' = 'left'

  konvaGroup: Konva.Group

  constructor() {
    this.konvaGroup = new Konva.Group()
    this.konvaGroup.on('mouseover touchmove', (e) => {
      this.mouseover(e)
    })
    this.konvaGroup.on('mouseout touchmove', (e) => {
      this.mouseout(e)
    })
  }

  draw(
    points: number[],
    width: number[],
    angle: number,
    scale: number,
    beginPillar: boolean,
    endPillar: boolean
  ): void {
    this.points = points
    this.width = width[0]
    if (width[0] < 800) return
    this.konvaGroup = drawDoorGroup(
      '',
      [points[0], points[1]],
      width[0],
      angle,
      scale,
      beginPillar,
      endPillar,
      true
    ).door
  }

  mouseover(e: any): void {
    console.log('mouseover', e)
  }

  mouseout(e: any): void {
    console.log('mouseout', e)
  }

  clickOn(e: any): void {}

  dbClickOn(e: any): void {
    console.log('dbClickOn', e)
  }

  remove(e: any): void {}
}
